#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/3/8 17:05
# @Author  : jeff
# @FileName: redis_cache
import redis

from src.utils.read_config import redis_config
from src.utils.singleton import Singleton

host_name, port, password = redis_config()


class RedisCache(metaclass=Singleton):
    def __init__(self, host, port, db=0, password='', ttl=6000):
        super().__init__()
        # 创建连接池
        self.pool = redis.ConnectionPool(
            host=host,
            port=port,
            db=db,
            password=password,
            max_connections=100,
            socket_keepalive=True,  # 保持长连接
            socket_timeout=30,  # socket 超时时间
            health_check_interval=60  # 每 30 秒检查连接健康状态（发送 PING）
        )
        # 使用连接池初始化 redis 客户端
        self.redis = redis.Redis(connection_pool=self.pool)
        self.ttl = ttl

    def update(self, k, v, ex=None):
        if ex is None:
            self.redis.set(name=k, value=v, ex=self.ttl)
        elif ex < 0:
            self.redis.set(name=k, value=v)
        else:
            self.redis.set(name=k, value=v, ex=ex)

    def get(self, k: object) -> object:
        v = self.redis.get(k)
        if v is None:
            return None
        else:
            v = v.decode('utf-8')
            return v

    def remove(self, k):
        self.redis.delete(k)

    def keys_by_pattern(self, pattern):
        keys = self.redis.keys(pattern)
        return [k.decode() for k in keys]

    def get_by_pattern(self, pattern):
        keys = self.keys_by_pattern(pattern)
        values = self.redis.mget(keys)
        return {k: v.decode() if v else None for k, v in zip(keys, values)}

    def delete_by_pattern(self, pattern):
        keys = self.keys_by_pattern(pattern)
        if keys:
            self.redis.delete(*keys)

    def keys(self):
        keys = self.redis.keys()
        return [k.decode() for k in keys]

    def exists(self, k):
        return self.redis.exists(k) > 0

    def expire(self, k, ex):
        self.redis.expire(k, ex)

    def ttl(self, k):
        return self.redis.ttl(k)

    def values(self):
        vs = self.redis.mget(self.keys())
        return [v.decode() if v else None for v in vs]

    def lpush(self, k, *values):
        """Push multiple values to a Redis list."""
        self.redis.lpush(k, *values)

    def lrange(self, k, start=0, end=-1):
        """Retrieve a range of values from a Redis list."""
        values = self.redis.lrange(k, start, end)
        return [v.decode('utf-8') for v in values]



redis_cache = RedisCache(host=host_name, port=port, password=password, )
